home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / kcl / akcl / akcl1615.lha / c / saveaix3.c < prev    next >
C/C++ Source or Header  |  1990-08-13  |  7KB  |  269 lines

  1. /*
  2. (c) Copyright Taiichi Yuasa and Masami Hagiya, 1984.  All rights reserved.
  3. Copying of this file is authorized to users who have executed the true and
  4. proper "License Agreement for Kyoto Common LISP" with SIGLISP.
  5.  
  6. (c) Copyright William F. Schelter.
  7.   
  8. */
  9. /*
  10.     unixsave.c
  11. */
  12. #ifndef UNIX
  13. #include "include.h"
  14. #endif
  15.  
  16. #include <fcntl.h>
  17. #include <filehdr.h>
  18. #include <aouthdr.h>
  19. #include <scnhdr.h>
  20. filecpy(to, from, n)
  21. FILE *to, *from;
  22. register int n;
  23. {
  24.     char buffer[BUFSIZ];
  25.     for (;;)
  26.         if (n > BUFSIZ) {
  27.             fread(buffer, BUFSIZ, 1, from);
  28.             fwrite(buffer, BUFSIZ, 1, to);
  29.             n -= BUFSIZ;
  30.         } 
  31.         else if (n > 0) {
  32.             fread(buffer, 1, n, from);
  33.             fwrite(buffer, 1, n, to);
  34.             break;
  35.         } 
  36.         else
  37.             break;
  38. }
  39. #include <sys/ldr.h>
  40. #include <loader.h>
  41. char *__start;
  42. memory_save(original_file, save_file)
  43. char *original_file, *save_file;
  44. {     /*   MEM_SAVE_LOCALS; */ 
  45.     struct filehdr Eheader;
  46.     struct aouthdr header;
  47.     struct scnhdr  shdrs[15];
  48.     int stsize;
  49.     int textsize=0;
  50.     int after_data;
  51.     int orig_data_scnptr;
  52.     int orig_debug_scnptr;
  53.  
  54.     char *data_begin, *data_end;
  55.     int original_data;
  56.     FILE *original, *save;
  57.     register int n;
  58.     register char *p;
  59.     extern char *sbrk();
  60.     extern char stdin_buf[BUFSIZ], stdout_buf[BUFSIZ];
  61.     fclose(stdin);
  62.     original = fopen(original_file, "r");
  63.     if (stdin != original || original->_file != 0) {
  64.       fprintf(stderr, "Can't open the original file.\n");
  65.       exit(1);
  66.     }
  67.     setbuf(original, stdin_buf);
  68.     fclose(stdout);
  69.     unlink(save_file);
  70.     n = open(save_file, O_CREAT|O_WRONLY, 0777);
  71.     if (n != 1 || (save = fdopen(n, "w")) != stdout) {
  72.       fprintf(stderr, "Can't open the save file.\n");
  73.       exit(1);
  74.     }
  75.     setbuf(save, stdout_buf);
  76.     /*    READ_HEADER; */
  77.     fread(&Eheader, sizeof(Eheader), 1, original);
  78.     fread(&header, sizeof(header), 1, original);
  79.     data_begin= 0x20000800;
  80.     {
  81.       char buf[500];
  82.       struct ld_info * ld;
  83.       loadquery(L_GETINFO,buf,sizeof(buf));
  84.       ld = (struct ld_info *)buf;
  85.       data_begin = ld->ldinfo_dataorg ;
  86.     }
  87.  
  88.     /*     header.data_start = data_begin; */
  89.  
  90.     data_end = core_end;
  91.     original_data = header.dsize;
  92.     header.dsize = data_end - data_begin;
  93.     header.bsize = 0;
  94.     {
  95.       int j,i = Eheader.f_nscns;
  96.       int diff;
  97.       fread(shdrs +1 ,i,sizeof(struct scnhdr),original);
  98.       orig_data_scnptr = shdrs[header.o_sndata].s_scnptr;
  99.       orig_debug_scnptr = shdrs[8].s_scnptr;
  100.       diff = header.a_data - original_data
  101.     - shdrs[header.o_snbss + 1].s_size;
  102.       after_data = shdrs[header.o_snbss +2].s_scnptr;
  103.       Eheader.f_symptr += diff;
  104.       fwrite(&Eheader, sizeof(Eheader), 1, save);
  105.       fwrite(&header, sizeof(header), 1, save);
  106.       shdrs[header.o_snbss ].s_size = 0;
  107.       shdrs[header.o_snbss +1 ].s_size = 0;
  108.       /* ex**pect no more than 15 sections, and pad after data */
  109.       if (strcmp(".pad",shdrs[header.o_snbss + 1].s_name)
  110.       || i >= 15)
  111.     perror("unexpected format of object file");
  112.       shdrs[header.o_sndata ].s_size = header.a_data;
  113.       /*       shdrs[header.o_sndata].s_paddr = data_begin;
  114.            shdrs[header.o_sndata].s_vaddr = data_begin;
  115.            */
  116.       for (j=1; j<= i; j++)
  117. #define ADJUST(x) if(x) (x) = (x) + diff                       
  118.     {
  119.       ADJUST(shdrs[j].s_lnnoptr);
  120.       ADJUST(shdrs[j].s_relptr);
  121.     }
  122.       for (j= header.o_sndata +1 ; j<= i; j++)
  123.     {
  124.       ADJUST(shdrs[j].s_scnptr);
  125.       ADJUST(shdrs[j].s_vaddr);
  126.       ADJUST(shdrs[j].s_paddr);
  127.     }
  128.       fwrite(shdrs +1  ,i,sizeof(struct scnhdr),save);
  129.  
  130.  
  131.       /*    FILECPY_HEADER; */
  132.       filecpy(save, original,
  133.           shdrs[header.o_sndata].s_scnptr
  134.           - sizeof(header)-sizeof(Eheader) - i*sizeof(struct scnhdr));
  135.  
  136.       j= ftell(save);
  137.       j= ftell(original);
  138.       for (n = header.a_data, p = data_begin;  ;  n -= BUFSIZ, p += BUFSIZ)
  139.     if (n > BUFSIZ)
  140.       fwrite(p, BUFSIZ, 1, save);
  141.     else if (n > 0) {
  142.       fwrite(p, 1, n, save);
  143.       break;
  144.     } 
  145.     else
  146.       break;
  147.       fseek(original, original_data, 1);
  148.       fseek(original, after_data, 0);
  149.  
  150.       /* now positioned at the loader section */
  151.       {
  152.     struct ldhdr *ldheader;
  153.     struct ldrel * ldreloc_info,*p;
  154.     char *space;
  155.     space = (char *)  sbrk(shdrs[header.o_snloader].s_size + 0x2000);
  156.     ldheader =  (struct ldhdr *) space;
  157.     fread(space,1,shdrs[header.o_snloader].s_size,original);
  158.     ldreloc_info = (struct ldrel *)
  159.       (space + sizeof(struct ldhdr) + LDSYMSZ * ldheader->l_nsyms);
  160.     i =  sizeof(struct ldhdr) + LDSYMSZ * (ldheader->l_nsyms);
  161.     for(p=ldreloc_info,i=0;  i< ldheader->l_nreloc ; i++,p++)
  162.       { 
  163.         if (p->l_rsecnm == header.o_snbss)
  164.           (p->l_rsecnm = header.o_sndata);
  165.         if (p->l_symndx == 2) /* make bss be data */
  166.           (p->l_symndx = 1);
  167.       }
  168.     /*         p->l_vaddr += data_begin; */
  169.     fwrite(ldheader, 1, shdrs[header.o_snloader].s_size,save);
  170.     /* unrelocate */
  171.     {
  172.       int j1 = ftell(save);
  173.       int j2= ftell(original);
  174.       int off=0;
  175.       fseek(original,orig_data_scnptr,0);
  176.       fseek(save,shdrs[header.o_sndata].s_scnptr,0);
  177.       for(p=ldreloc_info,i=0;  i< ldheader->l_nreloc ; i++,p++)
  178.         if (p->l_rsecnm == header.o_sndata)
  179.           {
  180.         int x,pos1,y;
  181.         int d = p->l_vaddr - off;
  182.         if (d)
  183.           {
  184.             fseek(save,d,1);
  185.             fseek(original,d,1);
  186.             off += d;
  187.           }
  188.         pos1 = ftell(original);
  189.         pos1 = ftell(save);
  190.         fread(&x,1,sizeof(int),original);
  191.         y = x;
  192.         if (p->l_symndx ==0)
  193.           { 
  194.             int w =  *((int *)&__start);
  195.             x = ((*(int *)(data_begin+off)));
  196.             x = x + header.text_start ;
  197.             x = x - w ;
  198.           }
  199.         if  (p->l_symndx ==1 || p->l_symndx ==2)
  200.           {
  201.             x = ((*(int *)(data_begin + off)) - (int) data_begin);
  202.           }
  203.         fwrite(&x,1,sizeof(int),save);
  204.         off += sizeof(int);
  205.           }
  206.       fseek(save,j1,0);
  207.       fseek(original,j2,0);
  208.  
  209.     }
  210.       }
  211.  
  212.       sbrk(- (shdrs[header.o_snloader].s_size+ 0x2000));
  213.       filecpy(save,original,Eheader.f_symptr - ftell(save));
  214.       /* now at the beginning of the sym table */
  215.       {
  216.     struct syment symbol;
  217.     struct syment *sym = &symbol;
  218.     int naux;
  219.     int nsyms = Eheader.f_nsyms;
  220.     while (--nsyms >= 0)
  221.       {
  222.         fread(&symbol,1,SYMESZ,original);
  223.         fwrite(&symbol,1,SYMESZ,save);
  224.         naux= sym->n_numaux;
  225.         nsyms = nsyms - naux;
  226.         if (ISFCN(sym->n_type)
  227.         && (naux >= 2))
  228.           { 
  229.         fread(&symbol,1,SYMESZ,original);
  230.         (((union auxent *)(sym))->x_sym.x_fcnary.x_fcn.x_lnnoptr) += diff;
  231.         fwrite(&symbol,1,SYMESZ,save);
  232.         filecpy(save,original,SYMESZ*(naux -1));
  233.           }
  234.         else
  235.           filecpy(save,original,SYMESZ*(naux));
  236.       }
  237.       }
  238.  
  239.  
  240.       COPY_TO_SAVE;
  241.       fclose(original);
  242.       fclose(save);
  243.     }
  244.   }
  245. Lsave()
  246. {
  247.     char filename[256];
  248.     check_arg(1);
  249.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  250.     coerce_to_filename(vs_base[0], filename);
  251.     _cleanup();
  252.     /*
  253.     {
  254.         FILE *p;
  255.         int nfile;
  256.         nfile = NUMBER_OPEN_FILES;
  257.         for (p = &_iob[3];  p < &_iob[nfile];  p++)
  258.             fclose(p);
  259.     }
  260. */
  261.     memory_save(kcl_self, filename);
  262.     _exit(0);
  263.     /*
  264.     exit(0);
  265. */
  266.     /*  no return  */
  267. }
  268.  
  269.